package com.yjk1.example.myFirstSofawebBoot.framework;

import org.mybatis.spring.mapper.ClassPathMapperScanner;
import org.springframework.beans.factory.config.BeanDefinitionHolder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.AnnotationMetadata;

import java.io.IOException;
import java.util.Set;

/**
 * @author yujiakui
 * @version 1.0
 * Email: jkyu@haiyi-info.com
 * date: 2018/11/13 9:17
 * description：
 **/
public class MybatisMapperScannerRegistrar implements ImportBeanDefinitionRegistrar, ResourceLoaderAware {

    private ResourceLoader resourceLoader;

    private static ClassPathMapperScanner scanner;

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {
        this.resourceLoader = resourceLoader;
    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
        ClassPathMapperScanner scanner = new ClassPathMapperScanner(registry);

        // this check is needed in Spring 3.1
        if (resourceLoader != null) {
            scanner.setResourceLoader(resourceLoader);
        }

//        scanner.setAnnotationClass(Annotation.class);
//        scanner.setMarkerInterface(Class.class);
//        scanner.setBeanNameGenerator(BeanUtils.instantiateClass(BeanNameGenerator.class));
//        scanner.setMapperFactoryBean(BeanUtils.instantiateClass(MapperFactoryBean.class));

        scanner.setSqlSessionTemplateBeanName("");
        scanner.setSqlSessionFactoryBeanName("");

        scanner.registerFilters();
        MybatisMapperScannerRegistrar.scanner = scanner;
//        scanner.doScan(StringUtils.toStringArray(basePackages));
    }

    /**
     * 扫描mapper，将mapper动态加载进项目。
     * @param packageName   要扫描的包路径
     * @param resourceLoader       解析类路径的资源解析器，需指定类加载器
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Set<BeanDefinitionHolder> doScan(String packageName, ResourcePatternResolver resourceLoader) throws NoSuchFieldException, IllegalAccessException, IOException {


//        ReflectionUtils.doWithFields(ClassPathMapperScanner.class, new ReflectionUtils.FieldCallback() {
//            @Override
//            public void doWith(Field field) throws IllegalArgumentException, IllegalAccessException {
//                System.out.println("aaaaa");
//                field.set(scanner,resourceLoader);
//            }
//        }, new ReflectionUtils.FieldFilter() {
//            @Override
//            public boolean matches(Field field) {
//                return field.getName().equals("resourcePatternResolver");
//            }
//        });

        /**
         * 将scanner父类的父类，也就是ClassPathMapperScanner类中的resourcePatternResolver字段设置为resourceLoader
         */
//        final Class<?> superclass = scanner.getClass().getSuperclass().getSuperclass();
//        final Field field = superclass.getDeclaredField("resourcePatternResolver");
//        field.setAccessible(true);
//        field.set(scanner,resourceLoader);

        scanner.setResourceLoader(resourceLoader);
        return scanner.doScan(packageName);
//        for (BeanDefinitionHolder holder : beanDefinitionHolders) {
//            GenericBeanDefinition definition = (GenericBeanDefinition) holder.getBeanDefinition();
//            final Resource[] resources = resourceLoader.getResources("classpath*:com/luhui/**/*.**");
//            definition.setResource(resources[2]);
//            definition.setSource(resources[2]);
//        }
    }
}